package assignment4.part1;

import java.net.Socket;
import java.util.Random;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

public class Client {
	private final String address;
	private final int port;
	private Socket socket;
	private ObjectInputStream ois;
	private ObjectOutputStream oos;
	
	public Client(String address, int port){
		this.address = address;
		this.port = port;
		
		try{
			this.socket = new Socket(this.address, this.port);
			System.out.println("Socket created for " + this.address + ":" + this.port);
		}catch(IOException iex){
			System.out.println("Failed to initialize socket for " + this.address + ":" + this.port);
			System.exit(-1);
		}
		
		try{
			this.oos = new ObjectOutputStream(this.socket.getOutputStream());
		}catch(IOException iex){
			System.out.println("Failed to get output stream.");
			System.exit(-1);
		}
		
		try{
			this.ois = new ObjectInputStream(this.socket.getInputStream());
		}catch(IOException iex){
			System.out.println("Failed to get output stream.");
			System.exit(-1);
		}
	}
	
	/**
	 * Sends a text message to the server the client is connected to.
	 * @param msg The message to send
	 * @param toUpperCase Should the case be uppercase (true) or lowercase (false)
	 * @return True if the message was sent, false if not.
	 */
	public boolean sendMessage(String msg, boolean toUpperCase){
		try{
			System.out.println("Writing message: " + msg);
			this.oos.writeObject((toUpperCase ? 1 : 0));
			this.oos.writeObject(Encrypt.EncryptString(msg, SymmetricCrypt.password));
			this.oos.flush();
			return true;
		}catch(Exception ex){
			System.out.println("Failed to send message: " + msg);
			return false;
		}
	}
	
	/**
	 * Read a text message sent by the server.
	 * @return The message read.
	 */
	public String readMessage(){
		try {
			Object obj = ois.readObject();
			if(obj instanceof byte[]){
				byte[] read =(byte[])obj;
				return new String(Decrypt.DecryptString(read, SymmetricCrypt.password));
			}
		} catch (Exception e) {e.printStackTrace();}
		return "";
	}
	
	/**
	 * Close the connection to the server.
	 * @return True if the close was successful, false if not.
	 */
	public boolean close(){
		try{
			socket.close();
			return true;
		}catch(IOException iex){
			System.out.println("Failed to close socket.");
			return false;
		}
	}
	
	public static void main(String[] args) {
		String address = "localhost";
		int port = 34734;
		
		Client c = new Client(address, port);
		
		c.sendMessage("this is a test", true);
		System.out.println("Received: " + c.readMessage());
		
		c.sendMessage("now lets see if you can handle this loooooong string muhahaha", false);
		System.out.println("Received: " + c.readMessage());
	}
}
